package com.wkbb.basic.controller.open;

import com.wkbb.basic.config.BasicConfig;
import com.wkbb.basic.model.Organization;
import com.wkbb.basic.model.OrganizationWebank;
import com.wkbb.basic.service.OrganizationService;
import com.wkbb.basic.service.OrganizationWebankService;
import com.wkbb.basic.service.UserOpenService;
import com.wkbb.basic.service.UserService;
import com.wkbb.common.business.BasicBusiness;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.constants.VersionConstant;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.OrganizationDto;
import com.wkbb.common.enums.OrganizationTypeEnum;
import com.wkbb.common.redis.RedisTemplateUtil;
import com.wkbb.common.utils.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 基础模块对外接口
 */
@RestController
@Api(description = "组织模块对外接口")
@RequestMapping("/basic/{apiVersion}/open")
@Slf4j
public class OrganizationController {
    private final String defaultLogo = "https://cos.wkbaobao.com/default_logo.png";

    @Autowired
    private UserService userService;

    @Autowired
    private UserOpenService userOpenService;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    RedisTemplateUtil redisTemplateUtil;

    @Autowired
    private OrganizationWebankService organizationWebankService;

    @Autowired
    private BasicConfig basicConfig;

    @ApiOperation(value = "根据ID查询组织信息接口")
    @RequestMapping(value = "/getOrgById", method = RequestMethod.GET)
    public ResultDTO<OrganizationDto> getOrgById(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId) {
        log.info("***********OrganizationController.getOrgById******apiVersion:{},orgId:{}", apiVersion, orgId);
        try {

            if (null == orgId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            Organization organization = null;

            //取缓存
            String organizationRedisKey = BasicBusiness.getOrganizationRedisKey(orgId);
            organization = (Organization) redisTemplateUtil.get(organizationRedisKey);

            //缓存中没有则取数据库
            if (null == organization) {
                organization = organizationService.getByPrimaryKey(orgId);
                redisTemplateUtil.set(organizationRedisKey,organization,2, TimeUnit.HOURS);
            }

            OrganizationDto organizationDto = null;
            if (null != organization) {
                organizationDto = new OrganizationDto();
                BeanUtils.copyProperties(organization, organizationDto);
                organizationDto.setLogoImg(StringUtil.isEmpty(organizationDto.getLogoImg()) ? defaultLogo : organizationDto.getLogoImg());
            }

            return new ResultDTO<OrganizationDto>(organizationDto);
        } catch (Exception e) {
            log.error("***********OrganizationController.getOrgById******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据账户查询组织信息接口")
    @RequestMapping(value = "/getOrgByAccount", method = RequestMethod.GET)
    public ResultDTO<OrganizationDto> getOrgByAccount(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "账号ID", required = true) @RequestParam(name = "accountId", required = true) Long accountId) {
        log.info("***********OrganizationController.getOrgByAccount******apiVersion:{},accountId:{}", apiVersion, accountId);
        try {
            if (null == accountId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            Organization organization = organizationService.getOrgByAccount(accountId);
            OrganizationDto organizationDto = null;
            if (null != organization) {
                organizationDto = new OrganizationDto();
                BeanUtils.copyProperties(organization, organizationDto);
            }
            return new ResultDTO<OrganizationDto>(organizationDto);
        } catch (Exception e) {
            log.error("***********OrganizationController.getOrgByAccount******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据组织类型查询组织信息接口")
    @RequestMapping(value = "/getOrgByType", method = RequestMethod.GET)
    public ResultDTO<List<Organization>> getOrgByType(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织类型(1微看 2代理商 3机关 4集团 5幼儿园 6小学 7中职 8初中 9高中 10高职 11本科 12培训学校)", required = false) @RequestParam(name = "orgType", required = false) Integer orgType) {

        log.info("***********OrganizationController.getOrgByType******apiVersion:{},orgType:{}", apiVersion, orgType);
        try {
            Map<String, Object> params = new HashMap<>(1);
            if (orgType != null && orgType != 0) {
                params.put("orgType", orgType);
            }

            List<Organization> organizationList = organizationService.getListByMapParams(params);

            return new ResultDTO<List<Organization>>(organizationList);
        } catch (Exception e) {
            log.error("***********OrganizationController.getOrgByType******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据代理商查询学校信息接口")
    @RequestMapping(value = "/getOrgByAgent", method = RequestMethod.GET)
    public ResultDTO<List<Organization>> getOrgByAgent(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "代理商ID", required = true) @RequestParam(name = "agentId", required = true) Long agentId) {

        log.info("***********OrganizationController.getOrgByAgent******apiVersion:{},agentId:{}", apiVersion, agentId);
        try {
            if (null == agentId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            Map<String, Object> params = new HashMap<String, Object>();
            params.put("agentId", agentId);

            List<Organization> organizationList = organizationService.getListByMapParams(params);

            return new ResultDTO<List<Organization>>(organizationList);
        } catch (Exception e) {
            log.error("***********OrganizationController.getOrgByAgent******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据教育局查询学校信息接口")
    @RequestMapping(value = "/getOrgByEducation", method = RequestMethod.GET)
    public ResultDTO<List<OrganizationDto>> getOrgByEducation(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "教育局ID", required = true) @RequestParam(name = "educationId", required = true) Long educationId) {

        log.info("***********OrganizationController.getOrgByEducation******apiVersion:{},educationId:{}", apiVersion, educationId);
        try {
            if (null == educationId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            Map<String, Object> params = new HashMap<String, Object>();
            params.put("educationId", educationId);
            params.put("status", 1);

            List<Organization> organizationList = organizationService.getListByMapParams(params);
            List<OrganizationDto> organizationDtoList = tansEntity2Dto(organizationList);
            return new ResultDTO<List<OrganizationDto>>(organizationDtoList);
        } catch (Exception e) {
            log.error("***********OrganizationController.getOrgByEducation******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    /**
     * 临时方法,此方法在上线之后会被废弃
     * @param apiVersion
     * @param oldOrgIds
     * @return
     */
    @ApiOperation(value = "批量查询2.0版本学校ID")
    @RequestMapping(value = "getNewOrgListByOldIds", method = RequestMethod.GET)
    public ResultDTO<List<OrganizationDto>> getNewOrgListByOldIds(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织IDs", required = true) @RequestParam(name = "oldOrgIds", required = true) List<Long> oldOrgIds) {

        log.info("***********OrganizationController.getNewOrgListByOldIds******apiVersion:{},oldOrgIds:{}", apiVersion, oldOrgIds);

        try {
            return new ResultDTO<List<OrganizationDto>>(organizationService.getNewOrgListByOldIds(oldOrgIds));
        } catch (Exception e) {
            log.error("***********OrganizationController.getNewOrgListByOldIds******", e);
            return new ResultDTO<List<OrganizationDto>>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据用户ID查询代理商信息")
    @RequestMapping(value = "/getAgentInfoByUserId", method = RequestMethod.GET)
    public ResultDTO<OrganizationDto> getAgentInfoByUserId(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "educationId", required = true) Long userId) {

        log.info("***********OrganizationController.getAgentInfoByUserId******apiVersion:{},educationId:{}", apiVersion, userId);
        try {
            if (null == userId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            return new ResultDTO<OrganizationDto>(organizationService.getAgentInfoByUserId(userId));
        } catch (Exception e) {
            log.error("***********OrganizationController.getAgentInfoByUserId******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据用户ID查询学校信息")
    @RequestMapping(value = "/getOrgInfoByUserId", method = RequestMethod.GET)
    public ResultDTO<OrganizationDto> getOrgInfoByUserId(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "用户ID", required = true) @RequestParam(name = "educationId", required = true) Long userId) {

        log.info("***********OrganizationController.getOrgInfoByUserId******apiVersion:{},educationId:{}", apiVersion, userId);
        try {
            if (null == userId) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            return new ResultDTO<OrganizationDto>(organizationService.getOrgInfoByUserId(userId));
        } catch (Exception e) {
            log.error("***********OrganizationController.getOrgInfoByUserId******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据教育局查询学校信息接口")
    @RequestMapping(value = "getOrganizationList", method = RequestMethod.POST)
    public ResultDTO<List<OrganizationDto>> getOrganizationList(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "当前登录人所属教育局对象", required = true) @RequestBody OrganizationDto organizationDto) {

        log.info("***********OrganizationController.getOrganizationList******apiVersion:{},organizationDto:{}", apiVersion, organizationDto);
        try {
            if (null == organizationDto || null == organizationDto.getId()) {
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            List<Organization> organizationList = organizationService.getOrganizationList(organizationDto);
            List<OrganizationDto> organizationDtoList = tansEntity2Dto(organizationList);
            return new ResultDTO<List<OrganizationDto>>(organizationDtoList);
        } catch (Exception e) {
            log.error("***********OrganizationController.getOrganizationList******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    private List<OrganizationDto> tansEntity2Dto(List<Organization> organizationList){
        List<OrganizationDto> organizationDtoList = new ArrayList<OrganizationDto>(organizationList.size());
        if (!CollectionUtils.isEmpty(organizationList)) {
            OrganizationDto organizationDto = null;
            for (Organization organization : organizationList) {
                organizationDto = new OrganizationDto();
                BeanUtils.copyProperties(organization,organizationDto);
                organizationDtoList.add(organizationDto);
            }
        }
        return organizationDtoList;
    }

    @ApiOperation(value = "根据orgId清除学校数据接口")
    @PostMapping(value = "deleteOrganizationData")
    public ResultDTO deleteOrganizationData(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId){
        try{
            //在此验证必传参数
            if(null==orgId){
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }
            organizationService.deleteById(orgId);
            return new ResultDTO();
        }catch (Exception e){
            log.error("*************OrganizationController.deleteOrganizationData*************异常:{}", e.getMessage());
            return new ResultDTO(false);
        }
    }

    @ApiOperation(value = "查询所有申请中的APPID申请结果并绑定用户组")
    @RequestMapping(value = "searchAPPID",method = RequestMethod.GET)
    public ResultDTO<Object> searchAPPID(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion
    ) {

        log.info("***********OrganizationManageController.searchAPPID******apiVersion:{}", apiVersion);


        try {
            OrganizationWebank validOrganizationWebank = organizationWebankService.getValidOrganizationWebank();//取一个有用的webankappid用来调用查询appid的接口

            if(null==validOrganizationWebank){
                log.info("----------没有可用微众appid----------");
                return new ResultDTO<>(ErrorCode.GET_VALID_WEBANK_CONFIG);
            }
            organizationService.searchAPPID(validOrganizationWebank.getWebankAppid(),validOrganizationWebank.getWebankSecret(),validOrganizationWebank.getOrgId(),basicConfig.getWebankOrgId());

            return new ResultDTO<>();
        } catch (Exception e) {
            log.error("***********OrganizationManageController.add******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "修改学校类型接口(用于企微等第三方学校)")
    @RequestMapping(value = "/updateOrgType", method = RequestMethod.POST)
    public ResultDTO updateOrgType(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "学校ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId,
            @ApiParam(value = "组织类型(1微看 2代理商 3机关 4集团 5幼儿园 6小学 7中职 8初中 9高中 10高职 11本科 12培训学校)", required = true) @RequestParam(name = "orgType", required = true) Integer orgType) {

        log.info("***********OrganizationController.updateOrgType******orgId:{},orgType:{}", orgId, orgType);
        try {

            //在此验证必传参数
            if(null==orgId || null==orgType){
                return new ResultDTO<>(ErrorCode.PARAM_MISSING);
            }

            Organization organization = organizationService.getByPrimaryKey(orgId);
            if(null!=organization) {
                Organization school = new Organization();
                school.setId(orgId);
                school.setOrgType(orgType);
                organizationService.update(school);

                //清除缓存
                String organizationRedisKey = BasicBusiness.getOrganizationRedisKey(orgId);
                redisTemplateUtil.delete(organizationRedisKey);

                String smartOrganizationRedisKey = BasicBusiness.getSmartOrganizationRedisKey(organization.getSmartOrgId());
                redisTemplateUtil.delete(smartOrganizationRedisKey);
            }

            return new ResultDTO(true);
        } catch (Exception e) {
            log.error("***********OrganizationController.getOrgByType******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "根据来源类型查询组织信息接口")
    @RequestMapping(value = "/getOrgByOrigin", method = RequestMethod.GET)
    public ResultDTO<List<OrganizationDto>> getOrgByOrigin(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "来源(1自营 2智慧校园1.0 3企业微信 4访客 5智慧校园2.0)", required = false) @RequestParam(name = "origin", required = false) Integer origin) {

        log.info("***********OrganizationController.getOrgByOrigin******origin:{}", origin);
        try {
            Map<String, Object> params = new HashMap<>(1);
            if (origin != null && origin != 0) {
                params.put("origin", origin);
            }
            List<Organization> organizationList = organizationService.getListByMapParams(params);
            List<OrganizationDto> organizationDtoList = tansEntity2Dto(organizationList);
            return new ResultDTO<List<OrganizationDto>>(organizationDtoList);
        } catch (Exception e) {
            log.error("***********OrganizationController.getOrgByType******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "统计各类型学校个数数据")
    @RequestMapping(value = "/getOrgCountStatByOrgan", method = RequestMethod.GET)
    public ResultDTO<List<Map<String, Object>>> getOrgCountStatByOrgan(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId) {

        log.info("***********getOrgCountStatByOrgan******orgId:{}", orgId);
        try {

            Map<String, Object> params = new HashMap<String, Object>();

            Organization organization = organizationService.getByPrimaryKey(orgId);

            //判断是否是代理商
            if (OrganizationTypeEnum.AGENT.getValue().equals(organization.getOrgType())) {
                params.put("agentId", orgId);
            }

            //判断是否是教育局
            if (OrganizationTypeEnum.EDUCATION.getValue().equals(organization.getOrgType())) {
                OrganizationDto organizationDto = new OrganizationDto();
                organizationDto.setId(orgId);
                List<Organization> orgList = organizationService.getEducationList(OrganizationTypeEnum.EDUCATION.getValue(),organizationDto);
                if(orgList.size()==0) {
                    params.put("educationId", orgId);
                }
                else
                {
                    params.put("educationIds", orgList);
                }
            }

            //判断是否是集团
            if (OrganizationTypeEnum.CONGLOMERATE.getValue().equals(organization.getOrgType())) {
                params.put("conglomerateId", orgId);
            }

            List<Map<String, Object>> orgCountStatList = organizationService.getOrgCountStatByOrgan(params);
            return new ResultDTO<List<Map<String, Object>>>(orgCountStatList);

        } catch (Exception e) {
            log.error("***********getOrgCountStatByOrgan******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "统计学校总体数据")
    @RequestMapping(value = "/getOrgDataCount", method = RequestMethod.GET)
    public ResultDTO<Map<String, Integer>> getOrgDataCount(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId) {

        log.info("***********getOrgDataStat******orgId:{}", orgId);
        try {
            Map<String, Object> params = new HashMap<String, Object>();
            if (orgId != 1){
                params.put("orgId",orgId);
            }
            Map<String, Integer> orgCount = organizationService.getOrgDataCount(params);
            return new ResultDTO<>(orgCount);
        } catch (Exception e) {
            log.error("***********getOrgDataStat******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "统计学校总体数据")
    @RequestMapping(value = "/getOrgDataStat", method = RequestMethod.GET)
    public ResultDTO<List<Map<String, Object>>> getOrgDataStat(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId) {

        log.info("***********getOrgDataStat******orgId:{}", orgId);
        try {

            Map<String, Object> params = new HashMap<String, Object>();

//            Organization organization = organizationService.getByPrimaryKey(orgId);

            /*if(organization.getOrgType()<OrganizationTypeEnum.KINDERGARTEN.getValue()) {
                //判断是否是代理商
                if (OrganizationTypeEnum.AGENT.getValue().equals(organization.getOrgType())) {
                    params.put("agentId", orgId);
                }
                //判断是否是教育局
                else if (OrganizationTypeEnum.EDUCATION.getValue().equals(organization.getOrgType())) {
                    OrganizationDto organizationDto = new OrganizationDto();
                    organizationDto.setId(orgId);
                    List<Organization> orgList = organizationService.getEducationList(OrganizationTypeEnum.EDUCATION.getValue(), organizationDto);
                    if (orgList.size() == 0) {
                        params.put("educationId", orgId);
                    } else {
                        params.put("educationIds", orgList);
                    }
                }
                //判断是否是集团
                else if (OrganizationTypeEnum.CONGLOMERATE.getValue().equals(organization.getOrgType())) {
                    params.put("conglomerateId", orgId);
                }

                List<Map<String, Object>> orgList = organizationService.getOrgListByOrgan(params);
                params.put("orgIds",orgList);
            }
            else
            {
                params.put("orgId",orgId);
            }*/
            if (orgId != 1){
                params.put("orgId",orgId);
            }
            List<Map<String, Object>> orgCountStatList = organizationService.getOrgDataStat(params);
            return new ResultDTO<List<Map<String, Object>>>(orgCountStatList);

        } catch (Exception e) {
            log.error("***********getOrgDataStat******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    @ApiOperation(value = "查询城市下的学校")
    @RequestMapping(value = "/getOrgListByCity", method = RequestMethod.GET)
    public ResultDTO<List<OrganizationDto>> getOrgListByCity(
            @ApiParam(value = "接口版本", required = true, defaultValue = VersionConstant.V1) @PathVariable(value = "apiVersion", required = true) String apiVersion,
            @ApiParam(value = "组织ID", required = true) @RequestParam(name = "orgId", required = true) Long orgId)
    {
        log.info("***********getOrgListByCity******orgId:{}", orgId);
        try {
            return new ResultDTO(organizationService.getOrgListByCity(orgId));
        } catch (Exception e) {
            log.error("***********getOrgListByCity******", e);
            return new ResultDTO<>(ErrorCode.SYSTEM_EXCEPTION);
        }
    }
}
